package com.vt.common.security.util.parser;

import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.vt.admin.api.entity.SysDictionary;
import com.vt.common.core.annotation.DictText;
import com.vt.common.core.constant.CommonConstant;
import lombok.AllArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.*;

/**
 * @Auther: panZha
 * @Date: 2018/11/15 10:51
 * @Description:
 */
@Component
@AllArgsConstructor
public class DictionaryParser extends ResultDataParser{

    StringRedisTemplate redisTemplate;

    private final static String JOINER_SYMBOL = "@";
    private final static String SPLIT_SYMBOL = "=";

    @Override
    public void parse(Object data) {
        Collection cos = getResData(data);

        if (null == cos)
            return;

        Map<String, String> dictMap = null;
        for (Object obj : cos) {
            parseObj(obj, dictMap);
        }
    }

    private void parseObj(Object obj,
                          Map<String, String> dictMap) {

        Field[] fs = ReflectUtil.getFields(obj.getClass());

        Field field;
        Object code;
        Object v = "";
        DictText annotation;
        for (Field f : fs) {
            annotation = f.getAnnotation(DictText.class);

            if (null == annotation)
                continue;

            field = getIdField(f, fs);
            if (null == field)
                continue;

            if (StrUtil.isNotEmpty(annotation.group())) {

                //从字典数据解析
                if (null == dictMap)
                    dictMap = getDictMap();

                code = ReflectUtil.getFieldValue(obj, field);
                if (null == code)
                    continue;
                v = dictMap.get(Joiner.on(JOINER_SYMBOL).join(annotation.group(), code));

            } else if (annotation.custom().length > 0) {
                //custom
                Map<String, String> cMap = parseCustomStr(annotation.custom());
                v = cMap.get(String.valueOf(ReflectUtil.getFieldValue(obj, field)));
            }

            ReflectUtil.setFieldValue(obj, f, v);
        }
    }

    private Map<String, String> parseCustomStr(String[] custom) {
        Map<String, String> map = new HashMap();

        Splitter splitter = Splitter.on(SPLIT_SYMBOL);
        List<String> list;
        for (String str : custom) {
            list = splitter.splitToList(str);
            if (list.size() < 2)
                continue;

            map.put(list.get(0), list.get(1));
        }
        return map;
    }

    protected Field getIdField(Field f, Field[] fs) {
        DictText annotation = f.getAnnotation(DictText.class);
        if (null == annotation)
            return null;

        List<String> ss = new ArrayList(2);
        if (StrUtil.isNotEmpty(annotation.valField())) {
            ss.add(annotation.valField());
        } else {
            String s = removeSuffix(f.getName(), "Val", "Value", "Name");
            ss.add(s);
        }

        for (Field field : fs) {
            if (ss.contains(field.getName()))
                return field;
        }
        return null;
    }


    /**
     * @return key = type@value
     */
    private Map<String, String> getDictMap() {
        List<SysDictionary> list = JSONUtil.toList(
                JSONUtil.parseArray(redisTemplate.opsForValue().get(CommonConstant.REDIS_DICT_PREFIX)),
                SysDictionary.class);

        Map<String, String> map = new HashMap(list.size());

        Joiner joiner = Joiner.on(JOINER_SYMBOL);
        for (SysDictionary dict : list) {
            map.put(joiner.join(dict.getType(), dict.getValue()), dict.getText());
        }
        return map;
    }
}
